<!--
Copyright (c) 2025 The Khronos Group Inc.
Use of this source code is governed by an MIT-style license that can be
found in the LICENSE.txt file.
-->

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>WebGL Get Vertex Attrib Location Errors Test</title>
    <link rel="stylesheet" href="../../resources/js-test-style.css"/>
    <script src="../../js/js-test-pre.js"></script>
    <script src="../../js/webgl-test-utils.js"> </script>
</head>
<body>
<canvas id="one" width="50" height="50"></canvas>
<canvas id="two" width="50" height="50"></canvas>
<div id="description"></div>
<div id="console"></div>
<script>
"use strict";
description("Tests error conditions for getAttribLocation");
const wtu = WebGLTestUtils;

const canvas1 = document.getElementById("one");
const canvas2 = document.getElementById("two");
const gl1 = wtu.create3DContext(canvas1);
const gl2 = wtu.create3DContext(canvas2);

const notLinkedProgram = gl1.createProgram();
const deletedProgram = wtu.setupSimpleColorProgram(gl1);
gl1.deleteProgram(deletedProgram);

const validProgram = wtu.setupSimpleColorProgram(gl1);
const validProgramOtherContext = wtu.setupSimpleColorProgram(gl2);

function runTests() {
    for (const prefix of ["", "gl_", "webgl_", "_webgl_"]) {
        debug("");
        debug(`Running tests with ${prefix == '' ? 'no' : prefix} prefix`);

        if (!gl1.isContextLost()) {
            shouldBe("gl1.getAttribLocation(validProgram, 'vPosition')", "0");
        } else {
            shouldBe("gl1.getAttribLocation(validProgram, 'vPosition')", "-1");
        }
        wtu.glErrorShouldBe(gl1, gl1.NO_ERROR, "Valid attribute");

        shouldBe(`gl1.getAttribLocation(validProgram, '${prefix}unknown')`, "-1");
        wtu.glErrorShouldBe(gl1, gl1.NO_ERROR, "Not found attribute");

        const length = wtu.getDefault3DContextVersion() > 1 ? 1025 : 257;
        shouldBe(`gl1.getAttribLocation(validProgram, '${prefix}${"a".repeat(length)}')`, "-1");
        wtu.glErrorShouldBe(gl1, gl1.isContextLost() ? gl1.NO_ERROR : gl1.INVALID_VALUE,
                            "Too long attribute name");

        shouldBe(`gl1.getAttribLocation(validProgram, '${prefix}à')`, "-1");
        wtu.glErrorShouldBe(gl1, gl1.isContextLost() ? gl1.NO_ERROR : gl1.INVALID_VALUE,
                            "Attribute name with an unsupported character");

        shouldBe(`gl1.getAttribLocation(deletedProgram, '${prefix}vPosition')`, "-1");
        wtu.glErrorShouldBe(gl1, gl1.isContextLost() ? gl1.NO_ERROR : gl1.INVALID_VALUE,
                            "Deleted program");

        shouldBe(`gl1.getAttribLocation(validProgramOtherContext, '${prefix}vPosition')`, "-1");
        wtu.glErrorShouldBe(gl1, gl1.isContextLost() ? gl1.NO_ERROR : gl1.INVALID_OPERATION,
                            "Program from another context");

        shouldBe(`gl1.getAttribLocation(notLinkedProgram, '${prefix}vPosition')`, "-1");
        wtu.glErrorShouldBe(gl1, gl1.isContextLost() ? gl1.NO_ERROR : gl1.INVALID_OPERATION,
                            "Not linked program");
    }
}

runTests();

const ext = gl1.getExtension("WEBGL_lose_context");
if (ext) {
    canvas1.addEventListener("webglcontextlost", function (event) {
        event.preventDefault();

        setTimeout(function() {
            debug("");
            debug("Retrying all tests with lost context");
            wtu.glErrorShouldBe(gl1, gl1.CONTEXT_LOST_WEBGL);
            runTests();
            ext.restoreContext();
        }, 0);
    }, false);

    canvas1.addEventListener("webglcontextrestored", function (_) {
        debug("");
        debug("Test an invalidated program with a restored context");
        wtu.glErrorShouldBe(gl1, gl1.NO_ERROR, "No errors after context restore");

        shouldBeFalse("gl1.isProgram(validProgram)");
        shouldBe("gl1.getAttribLocation(validProgram, 'vPosition')", "-1");
        wtu.glErrorShouldBe(gl1, gl1.INVALID_OPERATION, "Program created before the context lost event");

        finishTest();
    }, false);

    ext.loseContext();
} else {
    finishTest();
}

var successfullyParsed = true;
</script>
</body>
</html>
